#include "canif.h"
#include "cantp_mainfunction.h"

#define BUFF_MAX_LENGTH 8

typedef struct
{
    rt_uint32_t id;
    rt_uint8_t data[8];
    rt_uint8_t dlc;
}Canif_FrameStruct;

/* 定义串CAN报文收发队列 */
#define MAX_MSGS    16
static struct rt_messagequeue cantp_read_queue;
static struct rt_messagequeue com_read_queue;
static struct rt_messagequeue can_write_queue;

Canif_FrameStruct cantp_read_msg_pool[MAX_MSGS];
Canif_FrameStruct com_read_msg_pool[MAX_MSGS];
Canif_FrameStruct can_write_msg_pool[MAX_MSGS];


/* CANIF 初始化函数 */
void Canif_Init(void)
{
    rt_err_t result = -RT_ERROR;

    result = rt_mq_init(&cantp_read_queue, "cantp_read_queue", cantp_read_msg_pool, sizeof(Canif_FrameStruct), sizeof(cantp_read_msg_pool), RT_IPC_FLAG_FIFO);
    if (RT_EOK != result)
    {
        rt_kprintf("Failed to initialize cantp_read_queue! Error code: %d\n", result);
        return;
    }

    result = rt_mq_init(&com_read_queue, "com_read_queue", com_read_msg_pool, sizeof(Canif_FrameStruct), sizeof(com_read_msg_pool), RT_IPC_FLAG_FIFO);
    if (RT_EOK != result)
    {
        rt_kprintf("Failed to initialize com_read_queue! Error code: %d\n", result);
        return;
    }

    result = rt_mq_init(&can_write_queue, "can_write_queue", can_write_msg_pool, sizeof(Canif_FrameStruct), sizeof(can_write_msg_pool), RT_IPC_FLAG_FIFO);
    if (RT_EOK != result)
    {
        rt_kprintf("Failed to initialize can_write_queue! Error code: %d\n", result);
        return;
    }
}

void Canif_MainFunction_Rx(void)
{
    Canif_FrameStruct can_frame;

    if ( RT_TRUE == can1_receive_frame( &(can_frame.id), can_frame.data, &(can_frame.dlc)) )
    {
        /* 如果为接收CAN帧的ID为UDS请求ID则写入CANTP BUFF，否则写入通信报文BUFF */
        if (can_frame.id == REQU_ID)
        {
            rt_mq_send(&cantp_read_queue, &can_frame, sizeof(Canif_FrameStruct));
        }
        else
        {
            rt_mq_send(&com_read_queue, &can_frame, sizeof(Canif_FrameStruct));
        }
    }
}

void Canif_MainFunction_Tx(void)
{
    Canif_FrameStruct can_frame;

    /* 发送can_write_queue中的所有CAN帧 */
    while ( RT_EOK == rt_mq_recv(&can_write_queue, &can_frame, sizeof(Canif_FrameStruct), RT_WAITING_NO) )
    {
        can1_send_frame(can_frame.id, can_frame.data, can_frame.dlc);
    }
}

rt_bool_t Canif_Cantp_send_frame(rt_uint32_t id, rt_uint8_t* msg, rt_uint32_t size)
{
    Canif_FrameStruct can_frame;

    can_frame.id = id;
    rt_memcpy(can_frame.data, msg, size);
    can_frame.dlc = size;

    if (RT_EOK == rt_mq_send(&can_write_queue, &can_frame, sizeof(Canif_FrameStruct)))
    {
        return RT_TRUE;
    }
    else
    {
        return RT_FALSE;
    }
}

rt_bool_t Canif_Cantp_receive_frame(rt_uint32_t* id, rt_uint8_t* msg, rt_uint32_t* size)
{
    Canif_FrameStruct can_frame;
    rt_bool_t retval = RT_FALSE;

    if ( RT_EOK == rt_mq_recv(&cantp_read_queue, &can_frame, sizeof(Canif_FrameStruct), RT_WAITING_NO) )
    {
        *id = can_frame.id;
        rt_memcpy(msg, can_frame.data, can_frame.dlc);
        *size = can_frame.dlc;
        retval = RT_TRUE;
    }
    return retval;
}

rt_bool_t Canif_Com_send_frame(rt_uint32_t id, rt_uint8_t* msg, rt_uint32_t size)
{
    Canif_FrameStruct can_frame;

    can_frame.id = id;
    rt_memcpy(can_frame.data, msg, size);
    can_frame.dlc = size;
    if (RT_EOK == rt_mq_send(&can_write_queue, &can_frame, sizeof(Canif_FrameStruct)))
    {
        return RT_TRUE;
    }
    else
    {
        return RT_FALSE;
    }
}

rt_bool_t Canif_Com_receive_frame(rt_uint32_t* id, rt_uint8_t* msg, rt_uint32_t* size)
{
    Canif_FrameStruct can_frame;
    rt_bool_t retval = RT_FALSE;

    if ( RT_EOK == rt_mq_recv(&com_read_queue, &can_frame, sizeof(Canif_FrameStruct), RT_WAITING_NO) )
    {
        *id = can_frame.id;
        rt_memcpy(msg, can_frame.data, can_frame.dlc);
        *size = can_frame.dlc;
        retval = RT_TRUE;
    }
    return retval;
}